// Created by lvyer on 2021/11/29.

// 1、动态注册 JNI函数
// 2、封装OpenGL工具类
// 3、着色器代码文件加载
// 4、C++实例保留（指针操作）
#include <jni.h>
#include <tools/LogTools.h>
#include <tools/JNITools.h>
#include <RendererControl.h>

#define NATIVE_JNI_CLASS_NAME "com/bytecodezz/app/learn3/NativeRenderer"

extern "C"
JNIEXPORT jlong JNICALL nativeJNIInitRenderer(JNIEnv *env, jobject thiz) {
    LOGD("nativeJNIInitRenderer");
    RendererControl *rendererControl = new RendererControl();
    rendererControl->init();
    return reinterpret_cast<jlong>(rendererControl);
}

extern "C"
JNIEXPORT void JNICALL
nativeJNISurfaceChange(JNIEnv *env, jobject thiz, jlong ptr, jint width, jint height) {
    LOGD("nativeJNISurfaceChange");
    RendererControl *rendererControl = reinterpret_cast<RendererControl *>(ptr);
    rendererControl->onSurfaceChanged(width, height);

}

extern "C"
JNIEXPORT void JNICALL nativeJNIDraw(JNIEnv *env, jobject thiz, jlong ptr) {
    LOGD("nativeJNIDraw");
    RendererControl *rendererControl = reinterpret_cast<RendererControl *>(ptr);
    rendererControl->draw();
}


extern "C"
JNIEXPORT jlong JNICALL nativeJNIInitFilterAlpha(JNIEnv *env, jobject thiz) {
    LOGD("nativeJNIInitFilterAlpha");
    return 0;
}

extern "C"
JNIEXPORT void JNICALL
nativeJNISwitchFilterAlpha(JNIEnv *env, jobject thiz, jlong ptr, jboolean isOpen) {
    RendererControl *rendererControl = reinterpret_cast<RendererControl *>(ptr);
    rendererControl->isOpenAlpha = isOpen;
    if (isOpen) {
        LOGD("nativeJNISwitchFilterAlpha : true");
    } else {
        LOGD("nativeJNISwitchFilterAlpha : false");
    }
}

extern "C"
JNIEXPORT void JNICALL
nativeJNIValueFilterAlpha(JNIEnv *env, jobject thiz, jlong ptr, jfloat value) {
    LOGD("nativeJNIValueFilterAlpha : %f", value);
    RendererControl *rendererControl = reinterpret_cast<RendererControl *>(ptr);
    rendererControl->setAlphaValue(value);
}

//{"方法名字符串","方法签名字符串",对应C层方法签名},
//{"native_Init","()V",(void *)(nativeInit)} 表示java层的方法名叫native_Init，无参数，void返回值，对应c层的方法为nativeInit(...)
static JNINativeMethod dynamicJniMethods[] = {
        {"nativeInitRenderer",      "()J",    (void *) nativeJNIInitRenderer},
        {"nativeSurfaceChange",     "(JII)V", (void *) nativeJNISurfaceChange},
        {"nativeDraw",              "(J)V",   (void *) nativeJNIDraw},
        {"nativeInitFilterAlpha",   "()J",    (void *) nativeJNIInitFilterAlpha},
        {"nativeFilterAlphaSwitch", "(JZ)V",  (void *) nativeJNISwitchFilterAlpha},
        {"nativeFilterAlphaValue",  "(JF)V",  (void *) nativeJNIValueFilterAlpha}
};

//加载lib库的时候首先被回调的方法
extern "C" jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    LOGD("JNI_OnLoad");
    JNIEnv *env = nullptr;
    //生成 jni环境变量
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return JNI_ERR;
    }
    //注册JNI函数
    jint regState = JNITools::registerNativeMethods(env, NATIVE_JNI_CLASS_NAME, dynamicJniMethods,
                                                    sizeof(dynamicJniMethods) /
                                                    sizeof(dynamicJniMethods[0]));
    if (regState != JNI_TRUE) {
        return JNI_ERR;
    }
    LOGD("JNI_OnLoad end");
    return JNI_VERSION_1_6;
}

extern "C" void JNI_OnUnload(JavaVM *vm, void *reserved) {
    JNIEnv *env = nullptr;
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return;
    }
    //注销 JNI函数
    JNITools::unRegisterNativeMethods(env, NATIVE_JNI_CLASS_NAME);
}
